package com.onlineMIS.ORM.DAO.headQ.custMgmt;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.collections.ComparatorUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.struts2.views.jsp.ui.HeadTag;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Projection;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.onlineMIS.ORM.DAO.BaseDAO;
import com.onlineMIS.ORM.DAO.Response;
import com.onlineMIS.ORM.DAO.headQ.barCodeGentor.HeadQEntityTagDaoImpl;
import com.onlineMIS.ORM.DAO.headQ.barCodeGentor.HeadQTagDaoImpl;
import com.onlineMIS.ORM.DAO.headQ.barCodeGentor.HeadQTagGroupDaoImpl;
import com.onlineMIS.ORM.DAO.headQ.finance.ChainAcctFlowDaoImpl;
import com.onlineMIS.ORM.DAO.headQ.finance.ChainFinanceTraceImpl;
import com.onlineMIS.ORM.entity.chainS.user.ChainStore;
import com.onlineMIS.ORM.entity.headQ.SQLServer.ClientsMS;
import com.onlineMIS.ORM.entity.headQ.barcodeGentor.HeadQTag;
import com.onlineMIS.ORM.entity.headQ.barcodeGentor.HeadQTagGroup;
import com.onlineMIS.ORM.entity.headQ.barcodeGentor.HeadqEntityTag;
import com.onlineMIS.ORM.entity.headQ.custMgmt.HeadQCust;
import com.onlineMIS.ORM.entity.headQ.custMgmt.HeadQCustVO;
import com.onlineMIS.ORM.entity.headQ.finance.ChainAcctFlow;
import com.onlineMIS.ORM.entity.headQ.finance.FinanceCategory;
import com.onlineMIS.ORM.entity.headQ.report.HeadQDealingsReportVO;
import com.onlineMIS.ORM.entity.headQ.supplier.supplierMgmt.HeadQSupplier;
import com.onlineMIS.action.headQ.custMgmt.HeadQCustMgmtFormBean;
import com.onlineMIS.action.headQ.report.HeadQReportFormBean;
import com.onlineMIS.common.Common_util;
import com.onlineMIS.common.loggerLocal;

@Repository
public class HeadQCustDaoImpl extends BaseDAO<HeadQCust> {
	
	@Autowired
	private HeadQEntityTagDaoImpl headQEntityTagDaoImpl;
	@Autowired
	private HeadQTagDaoImpl headQTagDaoImpl;
	@Autowired
	private ChainAcctFlowDaoImpl chainAcctFlowDaoImpl;
	@Autowired
	private ChainFinanceTraceImpl chainFinanceTraceImpl;


	public List<HeadQCust> getCustByPinyin(String pinyin, int status) {
		DetachedCriteria criteria = DetachedCriteria.forClass(HeadQCust.class);
		criteria.add(Restrictions.like("pinyin", pinyin + "%"));
		criteria.add(Restrictions.eq("status", status));

		return this.getByCritera(criteria, true);
	}

	public HeadQCust getAllCustObj() {
		HeadQCust cust = new HeadQCust();
		cust.setId(0);
		cust.setName("所有客户");
		return cust;
	}
	
	public HeadQCust getTemCust(Integer custId) {
		HeadQCust cust = new HeadQCust();
		if (custId == Common_util.ALL_RECORD) {
			cust = getAllCustObj();
		}else {
			cust = get(custId, true);
		}
		return cust;
	}

	public static HeadQCust getAllHeadCustObject() {
		HeadQCust headQCust = new HeadQCust();
		headQCust.setId(Common_util.ALL_RECORD);
		headQCust.setName("所有客户");
		headQCust.setArea("总部");
		return headQCust;
	}

	public List<HeadQCust> getAllHeadCust() {
		DetachedCriteria criteria = DetachedCriteria.forClass(ChainStore.class);
		criteria.add(Restrictions.ne("status", 0));
		return this.getByCritera(criteria, true);
	}



	
	/**
	 * 批量修改客户标签
	 * @param ids
	 * @param tagId
	 * @param type
	 * @return
	 */
	public Response saveOrUpdateEntityTags(Integer[] ids, String tagIdS) {
		Response response = new Response();
		List<Integer> custIds = new ArrayList<Integer>();
		List<String> tagIds = new ArrayList<String>();
		if (StringUtils.isNotEmpty(tagIdS)) {
			tagIds = Arrays.asList(tagIdS.split(","));
		}
		if (ids.length == 0) {
			response.setFail("客户信息为空，请选择客户");
		} else {
			custIds = Arrays.asList(ids);
			headQEntityTagDaoImpl.deleteTagByCustIds(custIds);
			if (tagIds.size() != 0) {
				for (Integer custId : ids) {
					for (String tagId : tagIds) {
						HeadqEntityTag entityTag = new HeadqEntityTag();
						entityTag.setEntityId(custId);
						entityTag.setTagId(Integer.valueOf(tagId));
						headQEntityTagDaoImpl.save(entityTag, true);
					}
				}
			}
			response.setSuccess("客户标签信息修改成功!");
		}
		return response;
	}
	

	

	/**
	 * 获取所有正常状态的客户
	 * @return
	 */
	public List<HeadQCust> selectCusts() {
		DetachedCriteria criteria = DetachedCriteria.forClass(HeadQCust.class);
		criteria.add(Restrictions.eq("status", HeadQCust.CustStatusEnum.GOOD.getKey()));

		List<HeadQCust> custs = getByCritera(criteria, true);
		return custs;
	}

	
	/**
	 * 根据客户名称模糊查询客户IDS
	 * @param custName
	 * @return
	 */
	public List<Integer> selectIdsByName(String custName,int custStatus) {
		List<Integer> ids = new ArrayList<Integer>();
		DetachedCriteria custCriteria = DetachedCriteria.forClass(HeadQCust.class);
		if (StringUtils.isNotBlank(custName)) {
			Pattern pattern = Pattern.compile("[A-Za-z]*");
			Matcher isNum = pattern.matcher(custName);
			
			if (isNum.matches() ) {
				custCriteria.add(Restrictions.like("pinyin", custName, MatchMode.ANYWHERE));
			}	else {
				custCriteria.add(Restrictions.like("name", custName, MatchMode.ANYWHERE));
			}				
		}	
		if (custStatus != Common_util.ALL_RECORD) {
			custCriteria.add(Restrictions.eq("status", custStatus));
		}		
		List<HeadQCust> custs =  this.getByCritera(custCriteria,true);
		if (custs.size() !=0) {
			for (HeadQCust headQCust : custs) {
				ids.add(headQCust.getId());
			}
		}
		return ids;
	}
	
	/**
	 * 根据客户名称模糊查询客户IDS
	 * @param custName
	 * @return
	 */
	public List<HeadQCust> selectCusts(String custName) {
		DetachedCriteria custCriteria = DetachedCriteria.forClass(HeadQCust.class);
		if (custName != null && custName != "") {
			Pattern pattern = Pattern.compile("[A-Za-z]*");
			Matcher isNum = pattern.matcher(custName);
			
			if (isNum.matches() ) {
				custCriteria.add(Restrictions.like("pinyin", custName, MatchMode.ANYWHERE));
			}	else {
				custCriteria.add(Restrictions.like("name", custName, MatchMode.ANYWHERE));
			}
		}		
		List<HeadQCust> custs =  this.getByCritera(custCriteria,true);
		return custs;
	}

	
	/**
	 * 根据客户ids查询客户信息
	 * @param custIds
	 * @return
	 */
	public List<HeadQCust> selectCustsByIds(List<Integer> custIds) {
		List<HeadQCust> list = new ArrayList<HeadQCust>();
		DetachedCriteria custCriteria = DetachedCriteria.forClass(HeadQCust.class);	
		custCriteria.add(Restrictions.eq("status", HeadQCust.CustStatusEnum.GOOD.getKey()));
		if (custIds.size()>0) {
			custCriteria.add(Restrictions.in("id", custIds));
			list = this.getByCritera(custCriteria, true);
		}else {
			return list;
		}
		return list;
	}

	
	/**
	 * 查询所有客户预存金合计
	 * @return
	 */
	public double selectPbAmount(int belongTo2) {
		List<Integer> qxCustIds = new ArrayList<Integer>();
		if(belongTo2 == FinanceCategory.BELONG_TO_QX) {
			qxCustIds = headQEntityTagDaoImpl.selectIdsByTagId(HeadQTag.HEADQ_QX_CUST_TAG_ID);
		}else if (belongTo2 == FinanceCategory.BELONG_TO_XLC) {
			qxCustIds = headQEntityTagDaoImpl.selectIdsByTagId(HeadQTag.HEADQ_XLC_CUST_TAG_ID);
		}
		DetachedCriteria criteria = DetachedCriteria.forClass(HeadQCust.class);
		criteria.add(Restrictions.in("id", qxCustIds));
		criteria.setProjection(Projections.sum("prepayInitialAmount"));
		List<Object> result = getByCriteriaProjection(criteria, true);
        return Common_util.getProjectionDoubleValue(result);
	}
	
	
	/**
	 * 当前欠款和预存金信息赋值
	 * @param custs
	 * @param result
	 * @return
	 * @throws ParseException
	 */
	public List<HeadQDealingsReportVO> selectNowInfo(List<HeadQCust> custs, List<HeadQDealingsReportVO> result) throws ParseException {
		
		Map<Integer, HeadQCust> cMap = new HashMap<Integer, HeadQCust>();
		List<Integer> ids = new ArrayList<Integer>();
		for (HeadQCust cust : custs) {
			cMap.put(cust.getId(), cust);
			ids.add(cust.getId());
		}
		Map<Integer, Double> dMap = chainAcctFlowDaoImpl.getAcctFlowAmtByIds(ids);
		Map<Integer,Double> rMap = chainFinanceTraceImpl.getSumOfFinanceCategory(ids);
		for (HeadQDealingsReportVO headQDealingsReportVO : result) {
			HeadQCust cust = cMap.get(headQDealingsReportVO.getClientId());
			
		    //当前欠款
			double currentFinance = cust.getInitialAcctBalance();
			if (dMap.get(cust.getId()) != null) {
				currentFinance += dMap.get(cust.getId());
			}
			currentFinance = Common_util.roundDouble(currentFinance, 2);
			//客户预存金
			double currentPrepayAmount = cust.getPrepayInitialAmount();
			if (rMap.get(cust.getId()) != null) {
				currentPrepayAmount += rMap.get(cust.getId());
			}
			currentPrepayAmount = Common_util.roundDouble(currentPrepayAmount, 2);
			headQDealingsReportVO.setNowDebt(currentFinance);
			headQDealingsReportVO.setNowPrestore(currentPrepayAmount);
		}

		return result;
	}

	
	/**
	 * 根据标签合集获取客户id集合
	 * @param tagIds
	 * @return
	 */
	public List<Integer> getTagGroupsCusts(String tagIds) {
		List<Integer> clientIds = new ArrayList<Integer>();
		if (StringUtils.isNotBlank(tagIds)) {
			List<String> tags = Arrays.asList(tagIds.split(","));
			if (tags.size() == 1) {
				tagIds.replaceAll(",", "");
			}		
			String hql = "select s1.entityId from HeadqEntityTag s1 where s1.tagId in (" + tagIds +") group by s1.entityId having count(s1.entityId) = "+tags.size();
			List<Object> values = this.executeHQLSelect(hql, null, null, true);
				if (values.size() != 0) {
					for (Object record : values) {					
						clientIds.add((Integer) record);
					}
				}	
		}	
		return clientIds;
		
	}

	/**
	 * 根据客户ID集合获取客户期初金额合计
	 * @param clientIds
	 * @return
	 */
	public double selectInitialAcctByIds(List<Integer> clientIds) {
		DetachedCriteria criteria = DetachedCriteria.forClass(HeadQCust.class);	
		criteria.add(Restrictions.eq("status", HeadQCust.CustStatusEnum.GOOD.getKey()));

		criteria.add(Restrictions.in("id", clientIds));
		
		
		criteria.setProjection(Projections.sum("initialAcctBalance"));
		
		List<Object> result = getByCriteriaProjection(criteria, true);

        return Common_util.getProjectionDoubleValue(result);
	}

	
	/**
	 * 根据客户ID集合获取客户当前欠款金额合计
	 * @param clientIds
	 * @return
	 */
	public double selectCurrentAcctByIds(List<Integer> clientIds) {
		DetachedCriteria criteria = DetachedCriteria.forClass(HeadQCust.class);	
		criteria.add(Restrictions.eq("status", HeadQCust.CustStatusEnum.GOOD.getKey()));

		criteria.add(Restrictions.in("id", clientIds));
		
		
		criteria.setProjection(Projections.sum("currentAcctBalance"));
		
		List<Object> result = getByCriteriaProjection(criteria, true);

        return Common_util.getProjectionDoubleValue(result);
	}

	/**
	 * 通过拼音查询客户信息
	 * @param pinyin
	 * @return
	 */
	public List<HeadQCust> selectCustsByPY(String pinyin, int status) {
		DetachedCriteria custCriteria = DetachedCriteria.forClass(HeadQCust.class);
		if (pinyin != null && pinyin != "") {
			Pattern pattern = Pattern.compile("[A-Za-z]*");
			Matcher isNum = pattern.matcher(pinyin);
			
			if (isNum.matches() ) {
				custCriteria.add(Restrictions.like("pinyin", pinyin, MatchMode.ANYWHERE));
			}	else {
				custCriteria.add(Restrictions.like("name", pinyin, MatchMode.ANYWHERE));
			}
			
			if (status != Common_util.ALL_RECORD)
				custCriteria.add(Restrictions.eq("status", status));
		}		
		List<HeadQCust> custs =  this.getByCritera(custCriteria,true);
		return custs;
	}
	

}
